<template>
  <div>
    <div class="map-container" :key="componentKey">
      <div class="map-controls">
        <el-button type="primary" @click="reloadComponent" :loading="loading" icon="Refresh">刷新</el-button>
        <el-button type="primary" @click="showPlotDrawer" icon="List">列表</el-button>
        <el-drawer title="地块列表" v-model="drawerVisible" :size="'25%'" :before-close="handleDrawerClose" class="custom-drawer">
          <el-table v-loading="loading" :data="plotList" stripe style="width: 100%"@row-click="handleRowClick":row-class-name="getRowClassName"highlight-current-row>
            <el-table-column label="地块名称" prop="name" align="center" />
            <el-table-column label="面积(平方米)" prop="area" align="center" />
            <el-table-column label="作物" prop="crop" align="center" />
            <el-table-column label="地块位置" prop="location" align="center" />
          </el-table>
        </el-drawer>
      </div>
      <div id="map"></div>
    </div>
  </div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount, reactive } from 'vue';
import { getUserProfile } from "@/api/system/user";
import 'leaflet/dist/leaflet.css';
import L from 'leaflet';
import 'leaflet-draw/dist/leaflet.draw.css';
import 'leaflet-draw';
import { ElMessage, ElMessageBox } from 'element-plus';
import { getPlotList, addPlot, updatePlot, deletePlot } from '@/api/peach/map';
import { listPlot } from "@/api/peach/plot";
const activeRowId = ref(null);
const map = ref(null);
const drawnItems = ref(null);
const drawControl = ref(null);
const polygonAreas = ref([]);
const showAreaInfo = ref(false);
const plotData = ref([]);
const loading = ref(false);
const componentKey = ref(0);
const initialCenter = [36.16052101045526, 117.159313];
const initialZoom = 18;
const drawerVisible = ref(false);
const plotList = ref([]);
const drawerloading = ref(false);
const state = reactive({ user: {}  });
const AMAP_KEY = '301462faa5f05d985f21a3dcb829dea1';
const AMAP_JSCODE = 'df46b427894e9d2b4fd25a5c38aa4ff5';
window._AMapSecurityConfig = {
  securityJsCode: AMAP_JSCODE
};
let __amapLoaded = false;
const ensureAMap = () =>
  new Promise((resolve, reject) => {
    if (window.AMap && __amapLoaded) return resolve(window.AMap);
    const script = document.createElement('script');
    script.src = `https://webapi.amap.com/maps?v=2.0&key=${AMAP_KEY}&plugin=AMap.Geocoder,AMap.Geolocation`;
    script.async = true;
    script.onload = () => {
      __amapLoaded = true;
      resolve(window.AMap);
    };
    script.onerror = reject;
    document.head.appendChild(script);
});

// 坐标转换,确保地址准确
const toGcj02FromLeafletLatLng = async (lat, lng) => [lng, lat];

const getBrowserCoords = () =>
  new Promise((resolve, reject) => {
    if (!navigator.geolocation) return reject(new Error('浏览器不支持定位'));
    navigator.geolocation.getCurrentPosition(resolve, reject, {
      enableHighAccuracy: true,
      timeout: 8000,
      maximumAge: 0
    });
});

// 使用地块中心点坐标自动填充地址 
const autoFillAddress = async (uniqueId, centerLatLng = null) => {
  try {
    const input = document.getElementById(`location_${uniqueId}`);
    if (!input) {
      console.debug('[定位] 未找到输入框:', `location_${uniqueId}`);
      return;
    }
    if (input.value?.trim()) {
      console.debug('[定位] 输入框已有值,跳过自动填充');
      return;
    }
    input.placeholder = '🌍 正在获取详细位置...';
    input.disabled = true;
    const AMap = await ensureAMap();
    const geocoder = new AMap.Geocoder({ 
      extensions: 'all',
      radius: 100 // 搜索半径100米,提高精度
    });
    let gcjLngLat;
    if (Array.isArray(centerLatLng) && centerLatLng.length === 2) {
      console.log('[定位] 使用地块中心点坐标:', centerLatLng);
      gcjLngLat = await toGcj02FromLeafletLatLng(centerLatLng[0], centerLatLng[1]);
      console.log('[定位] 转换后的GCJ-02坐标:', gcjLngLat);
    } else {
      console.log('[定位] 使用设备定位');
      const [lng, lat] = await getGcj02LngLat();
      gcjLngLat = [lng, lat];
    }
    geocoder.getAddress(gcjLngLat, (status, result) => {
      if (status === 'complete' && result?.regeocode) { // 使用逆地理编码获取地址
        const address = result.regeocode.formattedAddress || '';
        console.log('[定位] 获取到的地址:', address);
        input.value = address;
        input.placeholder = '地块位置';
        input.disabled = false;
        ElMessage.success({ message: '已自动填充详细地址', duration: 2000 });
      } else {
        console.warn('[逆地理] 失败:', status, result);
        throw new Error(result?.info || '逆地理编码失败');
      }
    });
  } catch (e) {
    console.error('[定位] 自动定位失败:', e?.message || e);
    const input = document.getElementById(`location_${uniqueId}`);
    if (input) {
      input.value = '';
      input.placeholder = '请手动输入地址';
      input.disabled = false;
    }
    ElMessage.warning({ message: '自动定位失败,请手动输入', duration: 2000 });
  }
};

const getGcj02LngLat = async () => {
  const AMap = await ensureAMap();
  return new Promise((resolve, reject) => {
    AMap.plugin('AMap.Geolocation', () => {
      const geo = new AMap.Geolocation({
        enableHighAccuracy: true,
        timeout: 8000
      });
      geo.getCurrentPosition(async (status, result) => {
        if (status === 'complete' && result?.position) {
          return resolve([result.position.lng, result.position.lat]);
        }
        try {
          const pos = await getBrowserCoords();
          const lnglat = [pos.coords.longitude, pos.coords.latitude];
          AMap.convertFrom(lnglat, 'gps', (s, r) => {
            if (s === 'complete' && r?.locations?.length) {
              const ll = r.locations[0];
              resolve([ll.lng, ll.lat]);
            } else {
              reject(new Error(r?.info || '坐标转换失败'));
            }
          });
        } catch (e) {
          reject(e);
        }
      });
    });
  });
};

const getUser = async () => {
  const response = await getUserProfile();
  state.user = response.data || {};
  window.currentUser = state.user;
};

getUser();

const getPlotInfoList = async () => {
  drawerloading.value = true;
  try {
    const response = await listPlot({
      pageNum: 1,
      pageSize: 50,
    });
    console.log("查询到的地块数据:", response.rows);
    plotList.value = response.rows;
  } catch (error) {
    ElMessage.error('加载地块列表失败');
  } finally {
    drawerloading.value = false;
  }
};

const showPlotDrawer = () => {
  console.log("显示地块按钮被点击");
  getPlotInfoList();
  drawerVisible.value = true;
};

const handleDrawerClose = () => {
  drawerVisible.value = false;
};

const handleRowClick = (row) => {
  console.log("点击了地块行:", row);
  const areaInfo = polygonAreas.value.find(info => info.id === row.id);
  if (!areaInfo || !areaInfo.layer) {
    ElMessage.warning('未找到对应的地块图层');
    return;
  }
  if (activeRowId.value === row.id) {
    areaInfo.layer.closePopup();
    activeRowId.value = null;
  } else {
    if (activeRowId.value !== null) {
      const prevAreaInfo = polygonAreas.value.find(info => info.id === activeRowId.value);
      if (prevAreaInfo && prevAreaInfo.layer) {
        prevAreaInfo.layer.closePopup();
      }
    }
    areaInfo.layer.openPopup();
    activeRowId.value = row.id;
    const center = calculatePolygonCenter(areaInfo.points);
    map.value.setView(center, map.value.getZoom(), {
      animate: true,
      duration: 0.5
    });
  }
};

const getRowClassName = ({ row }) => {
  return row.id === activeRowId.value ? 'active-row' : '';
};

const debounce = (func, wait) => {
  let timeout;
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
};

// 初始化地图
const initMap = () => {
  const standardMap = L.tileLayer(
    'http://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
    { subdomains: ['1', '2', '3', '4'], maxZoom: 20, minZoom: 3, attribution: '高德地图' }
  );
  const satelliteBaseMap = L.tileLayer(
    'https://webst0{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
    { subdomains: ['1', '2', '3', '4'], maxZoom: 20, minZoom: 3, attribution: '高德地图' }
  );
  const annotationLayer = L.tileLayer(
    'https://webst0{s}.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}',
    { subdomains: ['1', '2', '3', '4'], maxZoom: 20, minZoom: 3, attribution: '高德地图标注', opacity: 0.8 }
  );
  const satelliteMap = L.layerGroup([satelliteBaseMap, annotationLayer]);
  let mapCenter = initialCenter;
  let mapZoom = initialZoom;
  let defaultLayer = satelliteMap;
  if (window.tempMapState) {
    mapCenter = [window.tempMapState.center.lat, window.tempMapState.center.lng];
    mapZoom = window.tempMapState.zoom;
    defaultLayer = window.tempMapState.layerType === 'standard' ? standardMap : satelliteMap;
    delete window.tempMapState;
  }
  map.value = L.map('map', {
    center: mapCenter,
    zoom: mapZoom,
    layers: [defaultLayer],
    zoomControl: true,
    attributionControl: true
  });
  const baseLayers = { '卫星地图(含标注)': satelliteMap, '标准地图': standardMap };
  L.control.layers(baseLayers, null, { position: 'bottomleft' }).addTo(map.value);
  initDrawControls();
  const syncCenterUI = () => {
  if (!polygonAreas.value.length) return;
    polygonAreas.value.forEach((areaInfo) => {
      const center = calculatePolygonCenter(areaInfo.points);
      if (areaInfo.marker) areaInfo.marker.setLatLng(center);
      if (areaInfo.layer?.getPopup?.() && areaInfo.layer.isPopupOpen()) {
        areaInfo.layer.getPopup().setLatLng(center);
      }
    });
  };
  const syncCenterUIDebounced = debounce(() => {
    requestAnimationFrame(syncCenterUI);
  }, 16);
  // 在缩放/拖动结束时同步一次
  map.value.on('zoomend', syncCenterUIDebounced);
  map.value.on('moveend', syncCenterUIDebounced);
};

// 初始化绘制控件
const initDrawControls = () => {
  L.drawLocal = {
    draw: {
      toolbar: {
        actions: { title: '取消绘制', text: '取消' },
        finish: { title: '完成绘制', text: '完成' },
        undo: { title: '删除最后绘制的点', text: '删除最后一个点' },
        buttons: { polyline: '绘制线条',polygon: '绘制多边形',rectangle: '绘制矩形',circle: '绘制圆形',marker: '添加标记',circlemarker: '添加圆形标记'}
      },
      handlers: {
        circle: { tooltip: { start: '点击并拖拽绘制圆形' }, radius: '半径' },
        circlemarker: { tooltip: { start: '点击地图放置圆形标记' } },
        marker: { tooltip: { start: '点击地图放置标记' } },
        polygon: { tooltip: { start: '点击开始绘制',cont: '点击继续绘制',end: '点击第一个点完成绘制'}},
        polyline: { error: '<strong>错误:</strong> 图形边界不能相交!', tooltip: {start: '点击开始绘制线条',cont: '点击继续绘制线条',end: '点击最后一个点完成绘制'}
        },
        rectangle: { tooltip: { start: '点击并拖拽绘制矩形' } },
        simpleshape: { tooltip: { end: '释放鼠标完成绘制' } }
      }
    },
    edit: {
      toolbar: {
        actions: { save: { title: '保存更改', text: '保存' }, cancel: { title: '取消编辑,放弃所有更改', text: '取消' }, clearAll: { title: '清除所有图层', text: '全部清除' }},
        buttons: { edit: '编辑图层', remove: '删除图层' }
      },
      handlers: {
        edit: { tooltip: { text: '拖拽控制点或标记来编辑图形',subtext: '点击取消按钮撤销更改'}},
        remove: { tooltip: { text: '点击要删除的图形' } }
      }
    }
  };
  drawnItems.value = new L.FeatureGroup();
  map.value.addLayer(drawnItems.value);
  const drawControlOptions = {
    position: 'topleft',
    draw: {
      polyline: false,
      polygon: {
        allowIntersection: false,
        drawError: { color: '#e1e100', message: '<strong>错误:</strong> 多边形边界不能相交!'},
        shapeOptions: { color: '#97009c', weight: 3, opacity: 0.8, fillOpacity: 0.2 },
        showArea: false,
        metric: true,
        feet: false,
        repeatMode: false
      },
      circle: false,
      rectangle: false,
      marker: false,
      circlemarker: false
    },
    edit: { featureGroup: drawnItems.value, remove: false, edit: false}
  };
  drawControl.value = new L.Control.Draw(drawControlOptions);
  map.value.addControl(drawControl.value);
  map.value.on(L.Draw.Event.CREATED, onDrawCreated);
  map.value.on(L.Draw.Event.EDITED, onDrawEdited);
  map.value.on(L.Draw.Event.DELETED, onDrawDeleted);
};

const calculatePolygonArea = (layer) => {
  try {
    const latlngs = layer.getLatLngs()[0];
    if (!latlngs || latlngs.length < 3) {
      console.warn('坐标点数量不足,无法计算面积');
      return '0 m²';
    }
    const R = 6371000;
    const toRad = (deg) => deg * Math.PI / 180;
    let area = 0;
    const n = latlngs.length;
    for (let i = 0; i < n; i++) {
      const j = (i + 1) % n;
      const lat1 = toRad(latlngs[i].lat);
      const lng1 = toRad(latlngs[i].lng);
      const lat2 = toRad(latlngs[j].lat);
      const lng2 = toRad(latlngs[j].lng);
      area += (lng2 - lng1) * (2 + Math.sin(lat1) + Math.sin(lat2));
    }
    area = Math.abs(area * R * R / 2);
    if (area < 1) { area = 1;}
    if (area > 1000000) {
      area = (area / 1000000).toFixed(2);
      return `${area} km²`;
    } else {
      area = area.toFixed(2);
      return `${area} m²`;
    }
  } catch (error) {
    console.error('面积计算出错:', error);
    return '1 m²';
  }
};

// 处理绘制完成事件
const onDrawCreated = async (event) => {
  const layer = event.layer;
  const type = event.layerType;
  if (type === 'polygon') {
    setTimeout(async () => {
      const points = layer.getLatLngs()[0].map(latlng => [latlng.lat, latlng.lng]);
      const area = calculatePolygonArea(layer);
      if (area === '0 m²' || area === '0.00 m²') { ElMessage.warning('计算的面积过小,已设置为最小值1平方米');}
      const areaInfo = {
        id: Date.now(),
        layer: layer,
        area: area,
        points: points,
        name: '',
        location: '',
        crop: '',
        isNew: true
      };
      const popupContent = createEditablePopup(areaInfo, layer);
      layer.bindPopup(popupContent, {
        closeButton: true,
        autoClose: false,
        closeOnClick: false,
        maxWidth: 250,
        autoPan: false,
        keepInView: false,
        autoPanPadding: [0, 0]
      });
      const uniqueId = `popup_${areaInfo.id}`;
      // 弹窗打开时传递地块中心点坐标 
      layer.on('popupopen', () => {
        const center = calculatePolygonCenter(areaInfo.points); // [lat, lng]
        console.log('[弹窗打开] 使用地块中心点:', center);
        autoFillAddress(uniqueId, center);
      });
      const center = calculatePolygonCenter(areaInfo.points);
      const marker = L.marker(center);
      marker.on('mouseover', () => {
        if (layer && layer.getPopup()) {
          layer.openPopup();
        }
      });
      marker.on('mouseout', () => {
        setTimeout(() => {
          if (layer && layer.getPopup() && !layer.getPopup()._container?.matches(':hover')) {
            layer.closePopup();
          }
        }, 300);
      });
      layer.on('mouseover', () => { layer.openPopup();});
      layer.on('popupclose', () => {
        if (activeRowId.value === areaInfo.id) {
          activeRowId.value = null;
        }
      });
      layer.on('mouseout', () => {
        setTimeout(() => {
          if (layer && layer.getPopup() && !layer.getPopup()._container?.matches(':hover')) {
            layer.closePopup();
          }
        }, 300);
      });
      marker.bindTooltip(`地块ID: ${areaInfo.id}`, {
        permanent: false,
        direction: 'top',
        offset: [0, -10]
      });
      map.value.addLayer(marker);
      areaInfo.marker = marker;
      layer.openPopup();
      polygonAreas.value.push(areaInfo);
      showAreaNotification(areaInfo);
    }, 0);
  }
  drawnItems.value.addLayer(layer);
};

// 处理编辑完成事件
const onDrawEdited = async (event) => {
  const layers = event.layers;
  const currentCenter = map.value.getCenter();
  const currentZoom = map.value.getZoom();
  layers.eachLayer(async (layer) => {
    const areaInfo = polygonAreas.value.find(info => info.layer === layer);
    if (areaInfo) {
      const points = layer.getLatLngs()[0].map(latlng => [latlng.lat, latlng.lng]);
      const newArea = calculatePolygonArea(layer);
      areaInfo.area = newArea;
      areaInfo.points = points;
      // 更新标记位置
      if (areaInfo.marker) {
        const newCenter = calculatePolygonCenter(points);
        areaInfo.marker.setLatLng(newCenter);
      }
      const popupContent = createEditablePopup(areaInfo, layer);
      layer.setPopupContent(popupContent);
      if (areaInfo.marker) { areaInfo.marker.setTooltipContent(`地块ID: ${areaInfo.id}`);}
      showAreaNotification(areaInfo, '面积已更新');
    }
  });
  setTimeout(() => {
    map.value.setView(currentCenter, currentZoom, {
      animate: false,
      duration: 0
    });
  }, 0);
};

// 处理删除完成事件
const onDrawDeleted = async (event) => {
  const layers = event.layers;
  layers.eachLayer(async (layer) => {
    if (layer.plotData && layer.plotData.id) {
      try {
        await deletePlot(layer.plotData.id);
        ElMessage.success('地块删除成功');
        plotData.value = plotData.value.filter(plot => plot.id !== layer.plotData.id);
      } catch (error) {
        ElMessage.error('地块删除失败');
        console.error('删除地块失败:', error);
      }
    }
    const index = polygonAreas.value.findIndex(info => info.layer === layer);
    if (index !== -1) {
      const areaInfo = polygonAreas.value[index];
      if (areaInfo.marker && map.value.hasLayer(areaInfo.marker)) {
        map.value.removeLayer(areaInfo.marker);
      }
      polygonAreas.value.splice(index, 1);
    }
  });
};

const showAreaNotification = (areaInfo, message = '多边形绘制完成') => {
  ElMessage({
    message: `${message}!面积: ${areaInfo.area}`,
    type: 'success',
    duration: 3000,
    showClose: true
  });
};

const createEditablePopup = (areaInfo, layer) => {
  const uniqueId = `popup_${areaInfo.id}`;
  return `
    <div style="min-width: 220px; font-size: 12px;">
      <h4 style="margin: 3px 0; color: #333; text-align: center; font-size: 14px;">地块信息</h4>
      <div style="margin: 6px 0;">
        <label style="display: block; margin-bottom: 3px; font-weight: bold; font-size: 11px;">基地名称:</label>
        <input type="text" id="name_${uniqueId}" value="${areaInfo.name || ''}" style="width: 100%; padding: 3px; border: 1px solid #ddd; border-radius: 2px; font-size: 11px;" placeholder="请输入基地名称">
      </div>
      <div style="margin: 6px 0;">
        <label style="display: block; margin-bottom: 3px; font-weight: bold; font-size: 11px;">地址:</label>
        <input type="text" id="location_${uniqueId}" value="${areaInfo.location || ''}" style="width: 100%; padding: 3px; border: 1px solid #ddd; border-radius: 2px; font-size: 11px;" placeholder="请输入地址">
      </div>
      <div style="margin: 6px 0;">
        <label style="display: block; margin-bottom: 3px; font-weight: bold; font-size: 11px;">作物品种:</label>
        <input type="text" id="crop_${uniqueId}" value="${areaInfo.crop || ''}" style="width: 100%; padding: 3px; border: 1px solid #ddd; border-radius: 2px; font-size: 11px;" placeholder="请输入作物品种">
      </div>
      <div style="margin: 6px 0; text-align: center; background: #f5f5f5; padding: 4px; border-radius: 2px; font-size: 11px;">
        <strong>面积: ${areaInfo.area}</strong>
      </div>
      <div style="text-align: center; margin-top: 8px;">
        <button onclick="savePlotData('${uniqueId}', '${areaInfo.id}')" style="background: #409EFF; color: white; border: none; padding: 4px 8px; border-radius: 2px; margin-right: 5px; cursor: pointer; font-size: 11px;">
          保存
        </button>
        <button onclick="deletePlotData('${areaInfo.id}', ${areaInfo.isNew || false})" style="background: #f56c6c; color: white; border: none; padding: 4px 8px; border-radius: 2px; margin-right: 5px; cursor: pointer; font-size: 11px;">
          删除
        </button>
        <button onclick="cancelEdit('${uniqueId}')" style="background: #909399; color: white; border: none; padding: 4px 8px; border-radius: 2px; cursor: pointer; font-size: 11px;">
          取消
        </button>
      </div>
    </div>
  `;
};

const calculatePolygonCenter = (points) => {
  if (!points || !points.length) return [0, 0];
  let latSum = 0;
  let lngSum = 0;
  let count = 0;
  points.forEach(p => {
    const lat = Array.isArray(p) ? Number(p[0]) : Number(p?.lat);
    const lng = Array.isArray(p) ? Number(p[1]) : Number(p?.lng);
    if (Number.isFinite(lat) && Number.isFinite(lng)) {
      latSum += lat;
      lngSum += lng;
      count++;
    }
  });
  return count ? [latSum / count, lngSum / count] : [0, 0];
};

const reloadComponent = () => {
  try {
    loading.value = true;
    polygonAreas.value = [];
    plotData.value = [];
    if (map.value) {
      map.value.remove();
      map.value = null;
    }
    drawnItems.value = null;
    drawControl.value = null;
    componentKey.value += 1;
    setTimeout(() => {
      initMap();
      loadPlotData();
      ElMessage.success('组件重新加载成功');
      loading.value = false;
    }, 100);
  } catch (error) {
    ElMessage.error('组件重新加载失败');
    console.error('组件重新加载失败:', error);
    loading.value = false;
  }
};

// 从后端加载地块数据
const loadPlotData = async () => {
  try {
    loading.value = true;
    const response = await getPlotList({
      pageNum: 1,
      pageSize: 50 
    });
    const dataList = response?.rows || response?.data || [];
    plotData.value = dataList;
    if (!Array.isArray(plotData.value) || plotData.value.length === 0) {
      ElMessage.warning('没有加载到地块数据');
      return;
    }
    const normalizePoints = (raw) => {
      if (Array.isArray(raw)) {
        if (raw.length && !Array.isArray(raw[0]) && typeof raw[0] === 'object') {
          return raw
            .map(o => [Number(o.lat), Number(o.lng)])
            .filter(([lat, lng]) => Number.isFinite(lat) && Number.isFinite(lng));
        }
        return raw;
      }
      if (typeof raw === 'string') {
        let s = raw.trim();
        if ((s.startsWith("'") && s.endsWith("'")) || (s.startsWith('"') && s.endsWith('"'))) {
          s = s.slice(1, -1).trim();
        }
        if (s.includes(';')) {
          const pointPairs = s.split(';')
            .map(pair => pair.trim())
            .filter(pair => pair);
          return pointPairs.map(pair => {
            const [lngStr, latStr] = pair.split(',')
              .map(coord => coord.trim())
              .filter(coord => coord);
            const lat = Number(latStr);
            const lng = Number(lngStr);
            return Number.isFinite(lat) && Number.isFinite(lng) ? [lat, lng] : null;
          }).filter(Boolean);
        }
        try {
          const arr = JSON.parse(`[${s}]`);
          if (Array.isArray(arr) && arr.length) {
            if (!Array.isArray(arr[0]) && typeof arr[0] === 'object') {
              return arr
                .map(o => [Number(o.lat), Number(o.lng)])
                .filter(([lat, lng]) => Number.isFinite(lat) && Number.isFinite(lng));
            }
            return arr;
          }
        } catch (e) {
          console.warn('normalizePoints 解析失败:', s);
          return [];
        }
      }
      return [];
    };
    plotData.value.forEach(plot => {
      const parsedPoints = normalizePoints(plot.points);
      if (!parsedPoints.length) return;
      const latlngs = parsedPoints.map(coord => [coord[0], coord[1]]);
      const polygon = L.polygon(latlngs, {
        color: '#97009c',
        weight: 3,
        opacity: 0.8,
        fillOpacity: 0.2
      });
      polygon.plotData = plot;
      const areaText = calculatePolygonArea(polygon);
      const areaInfo = {
        id: plot.id,
        layer: polygon,
        area: areaText,
        points: parsedPoints,
        name: plot.name || '',
        location: plot.location || '',
        crop: plot.crop || '',
        isNew: false
      };
      const popupContent = createEditablePopup(areaInfo, polygon);
      polygon.bindPopup(popupContent, {
        closeButton: true,
        autoClose: false,
        closeOnClick: false,
        maxWidth: 250,
        autoPan: false,
        keepInView: false,
        autoPanPadding: [0, 0]
      });
      const uniqueId = `popup_${areaInfo.id}`;
      
      // 为保存的地块也传递中心点坐标 
      polygon.on('popupopen', () => {
        const center = calculatePolygonCenter(areaInfo.points);
        console.log('[已保存地块弹窗打开] 使用地块中心点:', center);
        autoFillAddress(uniqueId, center);
      });
      const centerPoint = calculatePolygonCenter(parsedPoints);
      const marker = L.marker(centerPoint);
      marker.on('mouseover', () => {
        if (polygon && polygon.getPopup()) {
          polygon.openPopup();
        }
      });
      marker.on('mouseout', () => {
        setTimeout(() => {
          if (polygon && polygon.getPopup() && !polygon.getPopup()._container?.matches(':hover')) {
            polygon.closePopup();
          }
        }, 300);
      });
      polygon.on('mouseover', () => {
        polygon.openPopup();
      });
      polygon.on('mouseout', () => {
        setTimeout(() => {
          if (polygon && polygon.getPopup() && !polygon.getPopup()._container?.matches(':hover')) {
            polygon.closePopup();
          }
        }, 300);
      });
      polygon.on('popupopen', (e) => {
        const popupElement = e.popup._container;
        if (popupElement) {
          popupElement.addEventListener('mouseenter', () => {
            popupElement.dataset.hover = 'true';
          });
          popupElement.addEventListener('mouseleave', () => {
            delete popupElement.dataset.hover;
            setTimeout(() => {
              if (!popupElement.matches(':hover')) {
                polygon.closePopup();
              }
            }, 100);
          });
        }
      });
      marker.bindTooltip(`地块ID: ${areaInfo.id}`, {
        permanent: false,
        direction: 'top',
        offset: [0, -10]
      });
      drawnItems.value.addLayer(polygon);
      map.value.addLayer(marker);
      areaInfo.marker = marker;
      polygonAreas.value.push(areaInfo);
    });
    ElMessage.success(`成功加载 ${plotData.value.length} 个地块`);
  } catch (error) {
    // ElMessage.error('加载地块数据失败');
    // console.error('加载地块数据失败:', error);
  } finally {
    loading.value = false;
  }
};

// 保存地块数据
window.savePlotData = async (uniqueId, areaId) => {
  const currentUser = window.currentUser;
  if (!currentUser || !currentUser.userId) {
    ElMessage.error('用户信息未加载,请重新登录或刷新页面');
    return;
  }
  
  const userId = currentUser.userId;
  const nameInput = document.getElementById(`name_${uniqueId}`);
  const locationInput = document.getElementById(`location_${uniqueId}`);
  const cropInput = document.getElementById(`crop_${uniqueId}`);

  if (!nameInput || !locationInput || !cropInput) {
    ElMessage.error('获取输入数据失败');
    return;
  }

  const name = nameInput.value.trim();
  const location = locationInput.value.trim();
  const crop = cropInput.value.trim();

  if (!name) {
    ElMessage.warning('请输入基地名称');
    return;
  }

  try {
    const currentCenter = map.value.getCenter();
    const currentZoom = map.value.getZoom();
    
    const areaInfo = polygonAreas.value.find(info => info.id == areaId);
    if (!areaInfo) {
      ElMessage.error('找不到对应的地块信息');
      return;
    }

    const pointsStr = Array.isArray(areaInfo.points)
      ? areaInfo.points.map(([lat, lng]) => `${lng}, ${lat}`).join(';')
      : String(areaInfo.points ?? '');

    const normalizeAreaToSquareMeters = (raw) => {
      const s = String(raw ?? '').trim();
      if (!s) return 0;
      const num = parseFloat(s.replace(/[^\d.-]/g, ''));
      if (!isFinite(num)) return 0;
      if (/km/i.test(s)) return +(num * 1_000_000).toFixed(2);
      return +num.toFixed(2);
    };

    const areaValue = normalizeAreaToSquareMeters(areaInfo.area);

    const plotDataToSave = {
      name,
      location,
      crop,
      points: pointsStr,
      area: areaValue,
      userId: userId
    };

    let savedPlot;
    
    if (areaInfo.layer.plotData && areaInfo.layer.plotData.id) {
      plotDataToSave.id = areaInfo.layer.plotData.id;
      savedPlot = await updatePlot(plotDataToSave);
      ElMessage.success('地块更新成功');
    } else {
      savedPlot = await addPlot(plotDataToSave);
      ElMessage.success('地块保存成功');
    }

    if (areaInfo.layer && areaInfo.layer.getPopup()?.isOpen()) {
      areaInfo.layer.closePopup();
    }

    await reloadPlotDataKeepView(currentCenter, currentZoom);
    
  } catch (error) {
    ElMessage.error('保存地块失败');
    console.error('保存地块失败:', error);
  }
};

window.deletePlotData = async (plotId, isNew = false) => {
  const currentUser = window.currentUser;
  if (!currentUser || !currentUser.userId) {
    ElMessage.error('用户信息未加载,请重新登录或刷新页面');
    return;
  }
  try {
    const confirm = await ElMessageBox.confirm('您确定要删除这个地块吗?', '删除地块', {
      confirmButtonText: '删除',
      cancelButtonText: '取消',
      type: 'warning',
    });
    if (confirm) {
      const currentCenter = map.value.getCenter();
      const currentZoom = map.value.getZoom();
      const areaInfo = polygonAreas.value.find(info => info.id == plotId);
      if (!areaInfo) {
        ElMessage.error('找不到要删除的地块');
        return;
      }
      if (isNew || !areaInfo.layer.plotData?.id) {
        if (areaInfo.layer) {
          if (drawnItems.value.hasLayer(areaInfo.layer)) { drawnItems.value.removeLayer(areaInfo.layer); }
        }
        if (areaInfo.marker && map.value.hasLayer(areaInfo.marker)) { map.value.removeLayer(areaInfo.marker); }
        const index = polygonAreas.value.findIndex(info => info.id == plotId);
        if (index !== -1) { polygonAreas.value.splice(index, 1); }
        ElMessage.success('地块已删除');
      } else {
        await deletePlot(areaInfo.layer.plotData.id);
        ElMessage.success('地块删除成功');
        await reloadPlotDataKeepView(currentCenter, currentZoom);
      }
    }
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('地块删除失败');
      console.error('地块删除失败:', error);
    }
  }
};

const reloadPlotDataKeepView = async (center, zoom) => {
  try {
    map.value.dragging.disable();
    map.value.scrollWheelZoom.disable();
    polygonAreas.value.forEach(areaInfo => {
      if (areaInfo.layer) {
        areaInfo.layer.off();
        if (drawnItems.value && drawnItems.value.hasLayer(areaInfo.layer)) {
          drawnItems.value.removeLayer(areaInfo.layer);
        }
      }
      if (areaInfo.marker) {
        areaInfo.marker.off();
        map.value.removeLayer(areaInfo.marker);
      }
    });
    polygonAreas.value = [];
    plotData.value = [];
    loading.value = true;
    const response = await getPlotList({
      pageNum: 1,
      pageSize: 50 
    });
    const dataList = response?.rows || response?.data || [];
    plotData.value = dataList;
    if (!Array.isArray(plotData.value) || plotData.value.length === 0) {
      map.value.setView(center, zoom, {
        animate: false,
        duration: 0
      });
      loading.value = false;
      map.value.dragging.enable();
      map.value.scrollWheelZoom.enable();
      return;
    }
    const normalizePoints = (raw) => {
      if (Array.isArray(raw)) {
        if (raw.length && !Array.isArray(raw[0]) && typeof raw[0] === 'object') {
          return raw
            .map(o => [Number(o.lat), Number(o.lng)])
            .filter(([lat, lng]) => Number.isFinite(lat) && Number.isFinite(lng));
        }
        return raw;
      }
      if (typeof raw === 'string') {
        let s = raw.trim();
        if ((s.startsWith("'") && s.endsWith("'")) || (s.startsWith('"') && s.endsWith('"'))) {
          s = s.slice(1, -1).trim();
        }
        if (s.includes(';')) {
          const pointPairs = s.split(';')
            .map(pair => pair.trim())
            .filter(pair => pair);
          return pointPairs.map(pair => {
            const [lngStr, latStr] = pair.split(',')
              .map(coord => coord.trim())
              .filter(coord => coord);
            const lat = Number(latStr);
            const lng = Number(lngStr);
            return Number.isFinite(lat) && Number.isFinite(lng) ? [lat, lng] : null;
          }).filter(Boolean);
        }
        try {
          const arr = JSON.parse(`[${s}]`);
          if (Array.isArray(arr) && arr.length) {
            if (!Array.isArray(arr[0]) && typeof arr[0] === 'object') {
              return arr
                .map(o => [Number(o.lat), Number(o.lng)])
                .filter(([lat, lng]) => Number.isFinite(lat) && Number.isFinite(lng));
            }
            return arr;
          }
        } catch (e) {
          console.warn('normalizePoints 解析失败:', s);
          return [];
        }
      }
      return [];
    };
    plotData.value.forEach(plot => {
      const parsedPoints = normalizePoints(plot.points);
      if (!parsedPoints.length) return;
      const latlngs = parsedPoints.map(coord => [coord[0], coord[1]]);
      const polygon = L.polygon(latlngs, {
        color: '#97009c',
        weight: 3,
        opacity: 0.8,
        fillOpacity: 0.2
      });
      polygon.plotData = plot;
      const areaText = calculatePolygonArea(polygon);
      const areaInfo = {
        id: plot.id,
        layer: polygon,
        area: areaText,
        points: parsedPoints,
        name: plot.name || '',
        location: plot.location || '',
        crop: plot.crop || ''
      };
      const popupContent = createEditablePopup(areaInfo, polygon);
      polygon.bindPopup(popupContent, {
        closeButton: true,
        autoClose: false,
        closeOnClick: false,
        maxWidth: 250,
        autoPan: false,
        keepInView: false,
        autoPanPadding: [0, 0]
      });
      const uniqueId = `popup_${areaInfo.id}`;
      polygon.on('popupopen', () => {
        const center = calculatePolygonCenter(areaInfo.points);
        autoFillAddress(uniqueId, center);
      });
      const centerPoint = calculatePolygonCenter(parsedPoints);
      const marker = L.marker(centerPoint);
      marker.on('mouseover', () => {
        if (polygon && polygon.getPopup()) {
          polygon.openPopup();
        }
      });
      marker.on('mouseout', () => {
        setTimeout(() => {
          if (polygon && polygon.getPopup() && !polygon.getPopup()._container?.matches(':hover')) {
            polygon.closePopup();
          }
        }, 300);
      });
      polygon.on('mouseover', () => {
        polygon.openPopup();
      });
      polygon.on('mouseout', () => {
        setTimeout(() => {
          if (polygon && polygon.getPopup() && !polygon.getPopup()._container?.matches(':hover')) {
            polygon.closePopup();
          }
        }, 300);
      });
      polygon.on('popupopen', (e) => {
        const popupElement = e.popup._container;
        if (popupElement) {
          popupElement.addEventListener('mouseenter', () => {
            popupElement.dataset.hover = 'true';
          });
          popupElement.addEventListener('mouseleave', () => {
            delete popupElement.dataset.hover;
            setTimeout(() => {
              if (!popupElement.matches(':hover')) {
                polygon.closePopup();
              }
            }, 100);
          });
        }
      });
      marker.bindTooltip(`地块ID: ${areaInfo.id}`, {
        permanent: false,
        direction: 'top',
        offset: [0, -10]
      });
      drawnItems.value.addLayer(polygon);
      map.value.addLayer(marker);
      areaInfo.marker = marker;
      polygonAreas.value.push(areaInfo);
    });
    requestAnimationFrame(() => {
      map.value.setView(center, zoom, {
        animate: false,
        duration: 0
      });
      map.value.invalidateSize({
        animate: false,
        pan: false
      });
      setTimeout(() => {
        map.value.setView(center, zoom, {
          animate: false,
          duration: 0
        });
        map.value.dragging.enable();
        map.value.scrollWheelZoom.enable();
        loading.value = false;
      }, 50);
    });
  } catch (error) {
    ElMessage.error('重新加载地块数据失败');
    console.error('重新加载失败:', error);
    loading.value = false;
    map.value.dragging.enable();
    map.value.scrollWheelZoom.enable();
  }
};

window.cancelEdit = (uniqueId) => {
  polygonAreas.value.forEach(areaInfo => {
    if (areaInfo.layer && areaInfo.layer.getPopup() && areaInfo.layer.getPopup().isOpen()) {
      areaInfo.layer.closePopup();
    }
  });
};

onMounted(async () => {
  initMap();
  setTimeout(async () => {
    await loadPlotData();
  }, 1000);
  
  window.addEventListener('resize', () => {
    if (map.value) {
      map.value.invalidateSize();
    }
  });
});

onBeforeUnmount(() => {
  if (map.value) {
    window.removeEventListener('resize', () => {
      if (map.value) { map.value.invalidateSize(); }
    });
    map.value.off(L.Draw.Event.CREATED, onDrawCreated);
    map.value.off(L.Draw.Event.EDITED, onDrawEdited);
    map.value.off(L.Draw.Event.DELETED, onDrawDeleted);
    if (drawControl.value) {
      map.value.removeControl(drawControl.value);
      drawControl.value = null;
    }
    if (drawnItems.value) {
      drawnItems.value.clearLayers();
      drawnItems.value = null;
    }
    polygonAreas.value = [];
    map.value.eachLayer(layer => {
      layer.remove();
    });
    if (map.value._controls) {
      map.value._controls.forEach(control => {
        if (control.remove) {
          control.remove();
        }
      });
    }
    map.value.remove();
    map.value = null;
  }
});

</script>
<style scoped>
.app-container {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
}

.map-container {
  position: relative;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  z-index: 2;
}

#map {
  height: calc(100vh - 84px);
  width: 100%;
  margin: 0;
  padding: 0;
  border: none;
}

.map-controls {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 1000;
  background: white;
  padding: 10px;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.custom-drawer {
  width: 25% !important;
  max-width: 25% !important;
  min-width: 25% !important;
}

/* 交互时高亮多边形边界 */
:deep(.leaflet-interactive:hover) {
  stroke-width: 5 !important;
  stroke-opacity: 1 !important;
}

/* 弹窗外观优化 */
:deep(.leaflet-popup-content-wrapper) {
  border-radius: 4px;
  box-shadow: 0 3px 14px rgba(0,0,0,0.3);
}

/* 标记悬浮效果 */
:deep(.leaflet-marker-icon:hover) {
  filter: brightness(1.2);
  cursor: pointer;
}

/* 表格选中行样式 */
:deep(.active-row) {
  background-color: #ecf5ff !important;
  font-weight: bold;
}

:deep(.active-row:hover > td) {
  background-color: #d9ecff !important;
}

:deep(.el-table__row) {
  cursor: pointer;
}

/* 关键修复：避免全局 img 样式导致 Leaflet 图标在缩放时“位移/漂移” */
:deep(.leaflet-container img.leaflet-marker-icon),
:deep(.leaflet-container img.leaflet-marker-shadow) {
  max-width: none !important;
  box-sizing: content-box !important;
}
/* 确保 Leaflet 里的图像完全不受全局 img/reset 影响 */
:deep(.leaflet-container img) {
  max-width: none !important;
  max-height: none !important;
  box-sizing: content-box !important;
}

/* 覆盖切片、标记、阴影、弹窗中的图片 */
:deep(.leaflet-container .leaflet-tile),
:deep(.leaflet-container img.leaflet-marker-icon),
:deep(.leaflet-container img.leaflet-marker-shadow),
:deep(.leaflet-container .leaflet-popup-content img) {
  max-width: none !important;
  max-height: none !important;
  box-sizing: content-box !important;
}

/* 防止父级 transform/缩放干扰（若上层有动画或缩放，可保底） */
.map-container, #map {
  transform: none !important;
  -webkit-transform: none !important;
}
</style>
